#模块：page_base
#董哥：报名学习：13760453683
#页面基类：封装了web自动化测试相关的一些属性、UI操作

import time
import autoit
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains


class PageBase(object):
    def __init__(self,driver,base_url):
        self.driver=driver
        self.base_url=base_url


    #功能：打开某url
    def open(self,pathUrl):
        self.driver.get(f"{self.base_url}{pathUrl}")

    #功能：自定义的定位函数
    def find_element(self,loc,isHightDisplay=False):
        by=loc[0]
        value=loc[1]
        ele=self.driver.find_element(by,value)
        if isHightDisplay:
            style = "background: green; border: 2px solid red;"
            self.driver.execute_script("arguments[0].setAttribute('style',arguments[1]);", ele, style)
        return ele

    def find_elements(self, loc):
        by = loc[0]
        value = loc[1]
        return self.driver.find_elements(by, value)

    #功能：点击某元素：也支持鼠标点击
    def click(self,loc,isHightDisplay=False,isMouseClick=False):
        ele =self.find_element(loc,isHightDisplay)
        if isMouseClick:
            ActionChains(self.driver).click(ele).perform()
        else:
            ele.click()

    #功能：输入元素.。也支持清空并输入
    #适合控件：文本框、密码框、多行文本框
    def input(self,loc,data,isHightDisplay=False,isClearAndInut=False):
        ele = self.find_element(loc,isHightDisplay)
        if isClearAndInut:#清空并输入
            ele.send_keys(Keys.CONTROL, 'a')  # ctrl+A
            ele.send_keys(Keys.BACK_SPACE)
        ele.send_keys(data)

    #功能：清空元素：失去焦点
    def clear(self,loc,isHightDisplay=False):
        ele = self.find_element(loc,isHightDisplay)
        ele.clear()

    #功能：获取元素的某属性/文本内容。支持：去除首尾空格
    def getEleAttrOrText(self,loc,type="text",attrName=None,isStrip=False):
        ele=ele=self.find_element(loc)
        if type=="text":#获取的文本内容
            data=ele.text
            if isStrip:
                data=data.strip()
            return data
        else:#获取某属性
            data=ele.get_attribute(attrName)
            if isStrip:
                data = data.strip()
            return data


    #功能：判断某元素是否在当前页面中存在
    def isExists(self,loc):
        try:
            self.find_element(loc)
            return True
        except Exception:
            return False


    #功能：单选按钮。选中某选项
    #<input type='radio' name='sex' value='M'>
    def click_radio(self,attrName,attrValue):
        ele_xuanzon=self.driver.find_element_by_css_selector(f"input[type='radio'][name='{attrName}'][value='{attrValue}']")
        ele_xuanzon.click()


    #功能：复选框。支持：全选、全不选、反选、选中0-N个指定选项
    def click_checkbox(self,attrName,type="指定N个选项",targetAttrValues=""):
        eles = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        if type=="全选":
              # List
            for x in eles:
                morenStatus = x.is_selected()
                if not morenStatus:
                    x.click()
        elif type=="全不选":
            for x in eles:
                morenStatus = x.is_selected()
                if morenStatus:
                    x.click()
        elif type=="反选":
            for x in eles:
                x.click()
        else: #指定N个选项
            for x in eles:
                attrValue = x.get_attribute("value")  # "dalanqiu"
                morenStatus = x.is_selected()
                if attrValue in targetAttrValues:
                    if not morenStatus:
                        x.click()
                else:
                    if morenStatus:
                        x.click()


    #功能：下拉列表。
    def click_select(self,selectAttrName,type="文本内容",data=None):
        ele_select = self.driver.find_element_by_css_selector(f"select[name='{selectAttrName}']")
        haha = Select(ele_select)
        if type=="文本内容":
            haha.select_by_visible_text(data)
        elif type=="下标":
            haha.select_by_index(data)
        else:
            haha.select_by_value(data)

    #功能：日期控件。输入日期值
    def input_riqi(self,loc,riqi,type="JS",isReadOnly=False):
        ele = self.find_element(loc)
        if isReadOnly:
            self.driver.execute_script("arguments[0].removeAttribute('readonly')", ele)
        if type=="JS":
            self.driver.execute_script("arguments[0].value=arguments[1]",ele,riqi)
        else:
            ele.send_keys(riqi)


    #功能：上传N个文件/目录。N>=0:
    def uploadFilesOrDirs(self,loc,filePaths,type="直接输"):
        if filePaths=="" or filePaths==None:
            return
        ele = self.find_element(loc)
        if type=="直接输":
            newFilePaths = filePaths.replace(",", "\n")
            ele.send_keys(newFilePaths)
        else:
            ActionChains(self.driver).click(ele).perform()
            time.sleep(2)

            newFilePaths = ""
            a = filePaths.split(",")
            for x in a:
                newFilePaths += '"' + x + '" '
            newFilePaths = newFilePaths.replace("/", "\\")

            autoit.win_wait("打开", 10)
            autoit.control_send("打开", "Edit1", newFilePaths)
            autoit.control_click("打开", "Button1")

    # 处理JS三种弹出框
    # 获取三种JS弹出框的文本内容
    def getTextForJsTanCuKuan(self):
        return self.driver.switch_to.alert.text

    # 点击三种JS弹出框的“确定”按钮
    def acceptForJsTanCuKuan(self):
        self.driver.switch_to.alert.accept()

    # 点击三种JS弹出框的“取消”按钮
    def dismissForJsTanCuKuan(self):
        self.driver.switch_to.alert.dismiss()

    # 为JS的prompt弹出框输入文本
    def inputJsTanCuKuan(self, data):
        self.driver.switch_to.alert.send_keys(data)


    #切换子网页相关
    #切换到某子网页中
    def switch_iframe(self,type="不是按元素",data=None):
        if type=="不是按元素":
            self.driver.switch_to.frame(data) #name/id/下标
        else:
            ele=self.find_element(data) #loc
            self.driver.switch_to.frame(ele) #WebElement对象

    #切回到主网页中
    def switch_defaultIframe(self):
        self.driver.switch_to.default_content()

    # 鼠标操作的相关处理

    # 函数功能：鼠标双击某元素loc
    def mouse_dbclick(self, loc, isHightDisplay=False):
        ele = self.find_element(loc, isHightDisplay)
        ActionChains(self.driver).double_click(ele).perform()

    # 函数功能：鼠标悬停在某元素loc
    def mouse_moveToEle(self, loc, isHightDisplay=False):
        ele = self.find_element(loc, isHightDisplay)
        ActionChains(self.driver).move_to_element(ele).perform()


    # 网页截图
    def savePng1(self, filePath):
        self.driver.get_screenshot_as_file(filePath)

    def savePng2(self, fileName):
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")

    def savePng3(self, serviceName, key):
        fileName = serviceName + "_" + key + "_" + time.strftime("%Y%m%d%H%M%S") #"登录_K001_20250605100314"
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")
        return fileName#"登录_K001_20250605100314"


    #切换window/标签页
    # 支持：根据窗口标题
    # 支持：根据窗口的url
    # 支持：切换到刚打开的那个窗口 / 最新窗口
    # 支持：切换到第N个窗口
    def switch_window(self,type="下标",data=-1):
        if type=="下标":
            self.driver.switch_to.window(self.driver.window_handles[data])
        elif type=="窗口标题":
            moren_handler = self.driver.current_window_handle
            flag = True  # 假设目标窗口不存在
            allWindows = self.driver.window_handles
            for one in allWindows:
                self.driver.switch_to.window(one)
                currentTitle = self.driver.title
                if data in currentTitle:
                    flag = False
                    break
                time.sleep(1)
            if flag:
                self.driver.switch_to.window(moren_handler)
        else:#窗口url
            moren_handler = self.driver.current_window_handle
            flag = True
            allWindows = self.driver.window_handles
            for one in allWindows:
                self.driver.switch_to.window(one)
                currentUrl = self.driver.current_url
                if data in currentUrl:
                    flag = False
                    break
                time.sleep(1)
            if flag:
                self.driver.switch_to.window(moren_handler)

